Skip to content

04 传输方式与客户端接入

MCP的数据层使用JSON-RPC消息,传输层负责在Client和Server之间传递这些消息。当前常用的标准传输方式主要有两类:stdio和Streamable HTTP。

选择传输方式时,应根据Server运行位置、部署方式、安全要求和并发需求判断。

一、传输方式对比

传输方式适用场景Server形态特点
stdio本地工具、本地开发、桌面客户端插件Client启动的子进程无需端口,启动简单,适合同机通信
Streamable HTTP远程工具、团队共享服务、Web部署独立HTTP服务支持远程访问、认证、多个Client连接

两种传输方式承载的是同一套MCP协议语义。差异主要在连接建立、消息传递和部署运维方式。

二、stdio传输

stdio传输中,MCP Client会把Server作为子进程启动。Client通过Server的标准输入发送JSON-RPC消息,Server通过标准输出返回JSON-RPC消息。

text
MCP Client
  ├── 启动 Server 子进程
  ├── 写入 stdin
  └── 读取 stdout

stdio适合以下场景:

  • 本地文件系统工具
  • 本地Git仓库工具
  • 桌面客户端连接的本地Server
  • 开发和调试阶段
  • 不需要远程访问的内部工具

2.1 stdio启动示例

Python Server中可以这样启动:

python
def main():
    mcp.run(transport="stdio")


if __name__ == "__main__":
    main()

客户端配置通常需要指定命令和参数:

json
{
  "mcpServers": {
    "docs": {
      "command": "uv",
      "args": [
        "--directory",
        "/ABSOLUTE/PATH/docs-mcp-server",
        "run",
        "server.py"
      ]
    }
  }
}

配置要点:

  • 使用绝对路径,避免Host工作目录不确定导致启动失败。
  • 不要把业务日志写入stdout
  • 需要的环境变量应显式配置。

2.2 环境变量配置

本地Host启动Server时,继承的环境变量可能有限。需要API Key、数据库地址等配置时,应在客户端配置中显式写入:

json
{
  "mcpServers": {
    "docs": {
      "command": "uv",
      "args": [
        "--directory",
        "/ABSOLUTE/PATH/docs-mcp-server",
        "run",
        "server.py"
      ],
      "env": {
        "DOCS_API_KEY": "your-api-key",
        "DOCS_BASE_URL": "https://docs.example.com"
      }
    }
  }
}

生产环境中不建议把敏感信息直接提交到仓库,应使用客户端支持的安全配置方式或系统密钥管理方案。

三、Streamable HTTP传输

Streamable HTTP适合远程MCP Server。Server作为独立HTTP服务运行,Client通过HTTP POST发送JSON-RPC消息,也可以通过SSE接收流式消息或通知。

text
MCP Client
  ↓ HTTP POST /mcp
MCP Server
  ↑ application/json 或 text/event-stream

Streamable HTTP适合以下场景:

  • 团队共享的工具服务
  • 企业内部统一MCP Server
  • 需要认证和权限控制的远程服务
  • 多个Host连接同一Server
  • 需要部署到容器或云服务的场景

3.1 HTTP Server示例

不同SDK版本对HTTP启动参数可能略有差异。使用FastMCP时,常见配置方式如下:

python
from mcp.server.fastmcp import FastMCP

mcp = FastMCP(
    "docs-server",
    host="127.0.0.1",
    port=8000,
    streamable_http_path="/mcp",
)


@mcp.tool()
def ping() -> str:
    """Health check tool."""
    return "pong"


if __name__ == "__main__":
    mcp.run(transport="streamable-http")

对应的Server地址为:

text
http://127.0.0.1:8000/mcp

本地开发时建议绑定127.0.0.1。如果绑定0.0.0.0,应确认网络访问范围、认证策略和防火墙配置。

3.2 HTTP客户端配置

远程Server通常通过URL接入:

json
{
  "mcpServers": {
    "docs": {
      "url": "https://mcp.example.com/mcp",
      "headers": {
        "Authorization": "Bearer your-token"
      }
    }
  }
}

不同Host的配置格式可能不同,但核心信息通常包括:

  • Server名称
  • MCP endpoint URL
  • 请求头
  • 认证信息
  • 超时或重试配置

四、stdio和HTTP如何选择

判断条件推荐方式
Server只在本机使用stdio
Server需要访问本地文件或本地Git仓库stdio
Server需要被多人共享Streamable HTTP
Server需要统一认证和审计Streamable HTTP
Server部署在容器或云服务中Streamable HTTP
开发早期快速验证stdio

可以先用stdio完成最小可用版本,再在需要共享或部署时改为HTTP服务。

五、连接生命周期

MCP连接建立后,会先进行初始化和能力协商。典型流程如下:

text
Client -> Server: initialize
Server -> Client: protocolVersion + capabilities + serverInfo
Client -> Server: notifications/initialized
Client -> Server: tools/list
Server -> Client: available tools

初始化阶段会协商:

  • 协议版本
  • Client能力
  • Server能力
  • Server名称和版本
  • 是否支持工具、资源、提示词、通知等

如果协议版本不兼容,Client和Server应终止连接或给出明确错误。

六、常见连接问题

问题可能原因处理方式
Server无法启动命令路径错误、依赖缺失、权限不足使用绝对路径,单独运行命令验证
Client看不到工具Server未声明工具能力,或初始化失败用Inspector查看initializetools/list
stdio连接后立即断开Server向stdout打印日志,破坏JSON-RPC日志改写到stderr
HTTP连接失败URL错误、端口未开放、路径不一致检查endpoint和网络访问
认证失败Token缺失或过期检查请求头和服务端认证逻辑
参数错误工具schema与调用参数不匹配检查工具定义和模型输入

七、部署建议

7.1 本地Server

本地Server应关注:

  • 使用绝对路径配置命令。
  • 不向stdout写业务日志。
  • 限制文件系统访问范围。
  • 对写入、删除类工具加入确认机制。
  • 避免在配置文件中硬编码敏感信息。

7.2 远程Server

远程Server应关注:

  • 使用HTTPS。
  • 实现认证和授权。
  • 校验Origin头,防止DNS rebinding攻击。
  • 本地调试服务绑定127.0.0.1
  • 对高风险工具加入审计和人工确认。
  • 记录工具调用日志和错误日志。

八、总结

MCP的传输层决定Server如何被Client连接。

传输方式核心特点
stdioClient启动Server子进程,通过标准输入输出通信
Streamable HTTPServer作为HTTP服务运行,支持远程连接和认证

本地工具优先使用stdio,共享服务优先使用Streamable HTTP。无论选择哪种方式,都应关注初始化、能力发现、日志输出和安全边界。